<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title></title>
    <style type="text/css">
        input[type="text"] {width: 300px;}
        .muted {color: #CCCCCC;font-size: 10px;}
    </style>
    <script type="text/javascript" src="https://unpkg.com/centrifuge@^5/dist/centrifuge.js"></script>
    <script type="text/javascript">
        // helper functions to work with escaping html.
        const tagsToReplace = {'&': '&amp;', '<': '&lt;', '>': '&gt;'};

        function replaceTag(tag) {
            return tagsToReplace[tag] || tag;
        }

        function safeTagsReplace(str) {
            return str.replace(/[&<>]/g, replaceTag);
        }

        const channel = "chat:index";

        window.addEventListener('load', function() {
            const input = document.getElementById("input");
            const container = document.getElementById('messages');

            const centrifuge = new Centrifuge('ws://localhost:8080/connection/websocket');

            centrifuge.on('connecting', function(ctx){
                drawText('Connecting: ' + ctx.reason);
                input.setAttribute('disabled', 'true');
            });

            centrifuge.on('disconnected', function(ctx){
                drawText('Disconnected: ' + ctx.reason);
                input.setAttribute('disabled', 'true');
            });

            // bind listeners on centrifuge object instance events.
            centrifuge.on('connected', function(ctx){
                drawText('Connected with client ID ' + ctx.client + ' over ' + ctx.transport + ' as user: ' + ctx.data.email);
                input.removeAttribute('disabled');
            });

            centrifuge.on('message', function (ctx) {
                drawText(JSON.stringify(ctx.data));
            });

            // subscribe on channel and bind various event listeners. Actual
            // subscription request will be sent after client connects to
            // a server.
            const sub = centrifuge.newSubscription(channel);

            sub.on("publication", handlePublication)
                .on("join", handleJoin)
                .on("leave", handleLeave)
                .on("unsubscribed", handleUnsubscribed)
                .on("subscribed", handleSubscribed)
                .on("subscribing", handleSubscribing)
                .on("error", handleSubscriptionError);

            sub.subscribe();

            // Trigger actual connection establishing with a server.
            // At this moment actual client work starts - i.e. subscriptions
            // defined start subscribing etc.
            centrifuge.connect();

            // show how many users currently in channel.
            function showPresence(sub) {
                sub.presence().then(function(result) {
                    let count = 0;
                    for (let key in result.clients){
                        count++;
                    }
                    drawText('Presence: now in this room – ' + count + ' clients');
                }, function(err) {
                    drawText("Presence error: " + JSON.stringify(err));
                });
            }

            function handleSubscribed(ctx) {
                drawText('Subscribed on channel ' + ctx.channel + ': ' + JSON.stringify(ctx));
                showPresence(sub);
            }

            function handleUnsubscribed(ctx) {
                drawText('Unsubscribed from channel ' + ctx.channel  + ', ' + JSON.stringify(ctx));
            }

            function handleSubscribing(ctx) {
                drawText('Subscribing on channel ' + ctx.channel  + ', ' + JSON.stringify(ctx));
            }

            function handleSubscriptionError(ctx) {
                drawText('Subscription error in channel ' + JSON.stringify(ctx));
            }

            function handlePublication(ctx) {
                let clientID;
                if (ctx.info){
                    clientID = ctx.info.client;
                } else {
                    clientID = null;
                }
                const inputText = ctx.data["input"].toString();
                const text = safeTagsReplace(inputText) + ' <span class="muted">from ' + clientID + '</span>';
                drawText(text);
            }

            function handleJoin(ctx) {
                drawText('Client joined channel ' + this.channel + ' (uid ' + ctx.info["client"] + ', user '+ ctx.info["user"] +')');
            }

            function handleLeave(ctx) {
                drawText('Client left channel ' + this.channel + ' (uid ' + ctx.info["client"] + ', user '+ ctx.info["user"] +')');
            }

            function drawText(text) {
                let e = document.createElement('li');
                e.innerHTML = [(new Date()).toString(), ' ' + text].join(':');
                container.insertBefore(e, container.firstChild);
            }

            document.getElementById('form').addEventListener('submit', function(event) {
                event.preventDefault();
                sub.publish({"input": input.value}).then(function () {
                    // console.log('message accepted by server');
                }, function (err) {
                    // console.log('error publishing message', err);
                });
                input.value = '';
            });
        });
    </script>
</head>
<body>
<form id="form">
    <input type="text" id="input" autocomplete="off"/>
    <input type="submit" id="submit" value="»">
</form>
<ul id="messages"></ul>
</body>
</html>
